package com.webcamtracker.tracker.example.browser;


import com.webcamtracker.move.tracking.AplicationListener;
import com.webcamtracker.move.tracking.TrackingEvent;
import com.webcamtracker.move.tracking.TrackingEventDispacher;
import com.webcamtracker.move.tracking.TrackingEventListener;
import com.webcamtracker.move.tracking.TrackingEventType;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.io.File;


public class FileBrowser
        extends JFrame implements AplicationListener {
    private BrowserManager browser = new BrowserManager();
    private ImageCanvas canvas = new ImageCanvas();

    private BackAction backAction;
    private NextAction nextAction;

    public FileBrowser() throws HeadlessException {
        super("File Browser");
        configureUI();
    }

    private void configureUI() {
        File dir = new File("/home/machaval/work/pictures");
        browser.load(dir);
        Container container = getContentPane();
        container.setLayout(new BorderLayout());
        JPanel panel = new JPanel(new GridLayout(1, 4));
        JPanel main = new JPanel(new BorderLayout());
        JButton back = new JButton("<<");
        JButton next = new JButton(">>");
        backAction = new BackAction();
        back.setAction(backAction);
        nextAction = new NextAction();
        next.setAction(nextAction);
        panel.add(new JPanel());
        panel.add(back);
        panel.add(next);
        panel.add(new JPanel());
        main.add(canvas, BorderLayout.CENTER);

        container.add(panel, BorderLayout.SOUTH);
        container.add(main, BorderLayout.CENTER);
        pack();
        setVisible(true);

    }


    public static void main(String[] args) {
        FileBrowser browser = new FileBrowser();

        browser.setSize(new Dimension(500, 500));
        browser.setVisible(true);


    }

    public void paint(File file) {
        ImageIcon imageIcon = new ImageIcon(file.getPath());
        Image image = imageIcon.getImage();
        canvas.setImage(image);
        canvas.repaint();
        setTitle(file.getName());
        pack();
    }

    public void subscribeToTracking(TrackingEventDispacher dispacher, String elementId) {
        dispacher.addTrackingEventListener(new TrackerActionListener() {
            void moveLeft() {
                System.out.println("FileBrowser.moveLeft");
                backAction.actionPerformed(null);
            }

            void moveCenter() {

                System.out.println("FileBrowser.moveCenter");
            }

            void moveRight() {
                System.out.println("FileBrowser.moveRight");
                nextAction.actionPerformed(null);
            }
        },
                TrackingEventType.ALL);
    }

    public class BackAction implements Action {

        public Object getValue(String key) {
            if (Action.NAME.equals(key)) {
                return "<<";
            }
            return null;
        }

        public void putValue(String key, Object value) {

        }

        public void setEnabled(boolean b) {

        }

        public boolean isEnabled() {

            return true;
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
        }

        public void actionPerformed(ActionEvent e) {
            System.out.println("FileBrowser$BackAction.actionPerformed");
            if (browser.hasBack()) {
                File file = browser.back();
                paint(file);
            }
        }
    }


    public class NextAction implements Action {

        public Object getValue(String key) {
            if (Action.NAME.equals(key)) {
                return ">>";
            }
            return null;
        }

        public void putValue(String key, Object value) {

        }

        public void setEnabled(boolean b) {

        }

        public boolean isEnabled() {
            return browser.hasNext();
        }

        public void addPropertyChangeListener(PropertyChangeListener listener) {
        }

        public void removePropertyChangeListener(PropertyChangeListener listener) {
        }

        public void actionPerformed(ActionEvent e) {
            System.out.println("FileBrowser$NextAction.actionPerformed");
            if (browser.hasNext()) {
                File file = browser.next();
                paint(file);
            }
        }
    }

    private abstract static class TrackerActionListener
            implements TrackingEventListener {
        private MoveState currentState = States.CENTER;
        private TrackingEvent previous;

        public void trackingEventDispatched(TrackingEvent event) {
            if (previous == null) {
                previous = event;
            } else {
                final int xDif = previous.getPoint().x - event.getPoint().x;
                final int yDif = previous.getPoint().y - event.getPoint().y;
                if (Math.abs(xDif) > (double) (event.getImage().getWidth() * (1 / 4f))) {
                    if (xDif < 0) {
                        MoveState s = currentState.moveRight();
                        if (s != currentState) {
                            if (s == States.RIGHT) {
                                moveRight();
                            }
                            if (s == States.CENTER) {
                                moveCenter();
                            }
                            currentState = s;
                        }
                    }
                    if (xDif > 0) {
                        MoveState s = currentState.moveLeft();
                        if (s != currentState) {
                            if (s == States.LEFT) {
                                moveLeft();
                            }
                            if (s == States.CENTER) {
                                moveCenter();
                            }
                            currentState = s;
                        }
                    }
                    previous = event;
                }
            }
        }

        abstract void moveLeft();

        abstract void moveCenter();

        abstract void moveRight();
    }

    public static class ImageCanvas extends Canvas {
        private Image image = null;


        public ImageCanvas() {
        }


        public void setImage(Image image) {
            this.image = image;
        }

        public void paint(Graphics g) {
            g.setColor(Color.BLACK);
            int maxWidth = (int) getPreferredSize().getWidth();
            int maxHeight = (int) getPreferredSize().getHeight();
            g.fillRect(0, 0, maxWidth, maxHeight);
            if (image != null) {
                int iwidth = image.getWidth(null);
                int iheight = image.getHeight(null);
                if (iwidth > iheight && iwidth > maxWidth) {
                    iheight = iheight * maxWidth / iwidth;
                    iwidth = maxWidth;
                } else if (iwidth < iheight && iheight > maxHeight) {
                    iwidth = iwidth * maxHeight / iheight;
                    iheight = maxHeight;
                }

                g.drawImage(image, (maxWidth - iwidth) / 2, (maxHeight - iheight) / 2, iwidth, iheight, null);
            }
        }
    }
}
